/**
 * 
 */
package co.fitstart.market.handler.impl;

import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.demo2do.core.support.Result;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.wechat.corp.handler.CorpMessageHandler;
import com.demo2do.core.wechat.corp.message.CorpMessage;
import com.demo2do.core.wechat.corp.message.CorpMessageStruct;
import com.demo2do.core.wechat.corp.message.CorpMessageStruct.CorpMessageStructBuilder;
import com.demo2do.core.wechat.corp.message.CorpMessageType;
import com.demo2do.core.wechat.handler.WechatHandler;
import com.demo2do.core.wechat.support.AppType;

import co.fitstart.market.handler.TencentHandler;
import co.fitstart.market.handler.support.MessageMapper;
import co.fitstart.market.handler.support.Target;


/**
 * @author downpour
 *
 */
@Component("tencentHandler")
public class TencentHandlerImpl implements TencentHandler {
    
    private static final Logger logger = LoggerFactory.getLogger(TencentHandler.class);
    
    @Value("#{ctx['enterprise.agentid']}")
    private int agentid;
    
    @Autowired
    private CorpMessageHandler corpMessageHandler;
    
    @Autowired
    private WechatHandler wechatHandler;

    /* (non-Javadoc)
     * @see co.fitstart.coach.handler.TencentHandler#sendMessage(java.lang.String, java.lang.String[])
     */
    @Async
    public void sendMessage(String message, String... mobiles) {
        
        MessageMapper messageMapper = this.generateMessageMapper(message, mobiles);
        
        CorpMessageStruct corpMessageStruct = this.generateCorpMessageStruct(messageMapper);
        
        logger.trace("#sendMessage with CorpMessageStruct["+ corpMessageStruct.asJsonString() +"]");
        
        try {
            
            Result result = corpMessageHandler.send(corpMessageStruct);
            
            if(result.isValid()) {
                
                result.success().message("发送消息成功");
                
                logger.trace("#sendMessage: send corpMessage success!");
                
            } else {
                
                logger.error("#sendMessage: send corpMessage fail with Result [" + JsonUtils.toJsonString(result) + "]");
                
                result.fail().message("发送消息失败");
            }
            
            
        } catch (Exception e) {
            
            logger.error("#sendMessage: occur expection ["+ e + "]");
        }
        
    }
    
    /**
     * 
     * @param message
     * @param mobiles
     * @return
     */
    private MessageMapper generateMessageMapper(String message,  String... mobiles) {
        
        List<String> targetIds = Arrays.asList(mobiles);
        
        MessageMapper messageMapper = new MessageMapper(message, targetIds, agentid, Target.USER, CorpMessageType.TEXT);
        
        return messageMapper;
    }
    
    /**
     * 
     * @param messageMapper
     * @return
     */
    private CorpMessageStruct generateCorpMessageStruct(MessageMapper messageMapper) {
        
        CorpMessageStructBuilder builder = messageMapper.initBuilder();
        
        CorpMessage corpMessage = messageMapper.initCorpMessgae();
        
        CorpMessageStruct corpMessageStruct = builder.build(corpMessage);
        
        return corpMessageStruct;
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.weixin.web.handler.WechatRecourseHandler#downloadResource(java.lang.String)
     */
    @SuppressWarnings("unchecked")
    public InputStream downloadResource(String mediaId) {
        
        InputStream inputStream = null;
        
        // Get access token as the API call credential
        String accessToken = wechatHandler.requestAccessToken(AppType.OFFICIAL);
        logger.trace("WechatResourceHandlerImpl#downloadResource() - Going to download resource with access token [{}] and mediaId [{}].", accessToken, mediaId);
        
        try {
            
            Response response = Request.Get(new URIBuilder("https://api.weixin.qq.com/cgi-bin/media/get")
                                                          .addParameter("access_token", accessToken)
                                                          .addParameter("media_id", mediaId)
                                                          .build())
                                                          .connectTimeout(10000)
                                                          .socketTimeout(10000)
                                                          .execute();

            // get http response
            HttpResponse httpResponse = response.returnResponse();
            logger.trace("WechatResourceHandlerImpl#downloadResource() - Get response status line [{}].", httpResponse.getStatusLine());
            
            HttpEntity httpEntity = httpResponse.getEntity();
            
            Header contentType =  httpEntity.getContentType();
            
            String mimeType = contentType.getValue();
            
            if(StringUtils.equalsIgnoreCase(mimeType, "image/jpeg")) {  // if response type is image, get input sttream
                
                inputStream = httpEntity.getContent();
                
            }else {  // else log body, and error
                
                String body = EntityUtils.toString(httpEntity, Consts.UTF_8);
                logger.trace("WechatpayHandlerImpl#downloadResource() - Get response body [{}].", body);
                
                Map<String, Object> data = JSON.parseObject(body, Map.class);
                int errcode = (Integer) data.get("errcode");
                String errmsg = (String) data.get("errmsg");
                
                if (errcode != 0) {
                  logger.error("WechatResourceHandlerImpl#downloadResource() - Download resource occurs error. The error code is [{}] and error message is [{}].", errcode, errmsg);
                }
            }
            
            // consume http entity
            EntityUtils.consume(httpEntity);
            
        } catch (URISyntaxException use) {
            logger.error("WechatResourceHandlerImpl#downloadResource() - URI builder encounters syntax exception: {}", use);
            
        } catch (IOException e) {
            logger.error("WechatResourceHandlerImpl#downloadResource() - Download resource encounters IO exception: {}", e);
        }
        
        return inputStream;
    }
}
